package com.elastic.test;

import com.elastic.model.Product;
import com.elastic.util.MyDataSource;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.metrics.Avg;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

import java.io.IOException;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @author: 李德才
 * @description:
 * @create: 2021-04-05 16:45
 **/
public class ElasticSearchClient_crud {

    static {
        new MyDataSource();
    }

    private static final String INDEX = "product";
    private static final String TYPE = "_doc";

    public static void main(String[] args) throws IOException {
        Settings settings = Settings.builder().put("cluster.name", "elasticsearch").build();
        TransportClient client = new PreBuiltTransportClient(settings)
//        TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
                .addTransportAddress(new TransportAddress(InetAddress.getByName("192.168.31.100"), 9300))//通讯端口  而不是服务端口
                .addTransportAddress(new TransportAddress(InetAddress.getByName("192.168.31.100"), 9301));
        //导入数据
//        create(client);
        //查询
//        getById(client);
//        getAll(client);
//        update(client);
//        delete(client);
//        multiSearch(client);
        aggSearch(client);
        client.close();

    }

    private static void create(TransportClient client) throws IOException {
        List<Product> list = Product.dao.findAll();
        for (Product item : list) {
            SimpleDateFormat format = new SimpleDateFormat("YYY-MM-dd");
            IndexResponse response = client.prepareIndex(INDEX, TYPE, item.getId().toString())
                    .setSource(XContentFactory.jsonBuilder()
                            .startObject()
                            .field("name", item.getName())
                            .field("desc", item.getDesc())
                            .field("price", item.getPrice())
                            .field("date", format.format(item.getCreatetime()))
                            .field("tags", item.getTags().split(","))
                            .endObject())
                    .get();
            System.out.println(response.getResult());
        }
    }


    public static void getById(TransportClient client) {
        GetResponse getResponse = client.prepareGet(INDEX, TYPE, "21").get();
        System.err.println(getResponse.getIndex());
        System.err.println(getResponse.getType());
        System.err.println(getResponse.getFields());
        System.err.println(getResponse.getId());
        System.err.println(getResponse.getVersion());
        System.err.println(getResponse.getSource());
    }

    public static void getAll(TransportClient client) {
        SearchResponse getResponse = client.prepareSearch(INDEX).get();
        System.err.println(getResponse.getHits());
        SearchHits hits = getResponse.getHits();
        SearchHit[] hits1 = hits.getHits();
        for (SearchHit documentFields : hits1) {
            String sourceAsString = documentFields.getSourceAsString();
            System.err.println(sourceAsString);
        }
    }

    public static void update(TransportClient client) throws IOException {
        XContentBuilder xContentBuilder = XContentFactory.jsonBuilder().startObject();
        xContentBuilder.field("name", "小米手机  update");
        xContentBuilder.endObject();
        UpdateResponse updateRequestBuilder = client.prepareUpdate(INDEX, TYPE, "21").setDoc(xContentBuilder).get();
        System.err.println(updateRequestBuilder.getResult());
    }

    public static void delete(TransportClient client) {
        DeleteResponse deleteResponse = client.prepareDelete(INDEX, TYPE, "23").get();
        System.err.println(deleteResponse.getResult());
        System.err.println(deleteResponse.status());
        System.err.println(convertStatus(deleteResponse));
    }

    public static void multiSearch(TransportClient client) {
        SearchRequestBuilder response = client.prepareSearch(INDEX);
        response.setQuery(QueryBuilders.matchQuery("name", "小米手机6"));
//        response.setQuery(QueryBuilders.matchPhraseQuery("name", "小米手机6"));
//        response.setPostFilter(QueryBuilders.rangeQuery("price").from(0).to(3002));
        response.setFrom(1).setSize(5);
        System.err.println(response.toString());
        SearchResponse responseResult = response.get();
        SearchHits hits = responseResult.getHits();
        hits.forEach(hit -> {
            String sourceAsString = hit.getSourceAsString();
            System.err.println(sourceAsString);
        });
    }

    private static boolean convertStatus(DocWriteResponse docWriteResponse) {
        return docWriteResponse.status().getStatus() == 200;
    }

    /**
     * 聚合查询
     * GET product/_search
     * {
     *   "size": 0,
     *   "aggs": {
     *     "group_by_month": {
     *       "date_histogram": {
     *         "field": "date",
     *         "interval": "month"
     *       },
     *       "aggs": {
     *         "by_tag": {
     *           "terms": {
     *             "field": "tags.keyword"
     *           },
     *           "aggs": {
     *             "avg_price": {
     *               "avg": {
     *                 "field": "price"
     *               }
     *             }
     *           }
     *         }
     *       }
     *     }
     *   }
     * }
     **/
    public static void aggSearch(TransportClient client) {
        SearchResponse searchResponse = client.prepareSearch("product").addAggregation(
//                aggs
                AggregationBuilders.dateHistogram("group_by_month").field("date").dateHistogramInterval(DateHistogramInterval.MONTH)
                        .subAggregation(
//                                aggs
                         AggregationBuilders.terms("by_tag").field("tags.keyword").subAggregation(
                                AggregationBuilders.avg("avg_price").field("proce")))).execute().actionGet();
        SearchHit[] hits = searchResponse.getHits().getHits();
        Map<String, Aggregation> aggregationMap = searchResponse.getAggregations().asMap();
        Aggregation group_by_month = aggregationMap.get("group_by_month");
        Histogram dates = (Histogram) group_by_month;
        Iterator<Histogram.Bucket> buckets = (Iterator<Histogram.Bucket>) dates.getBuckets().iterator();

        while (buckets.hasNext()) {
            Histogram.Bucket dateBucket = buckets.next();
            System.out.println("\n\n月份：" + dateBucket.getKeyAsString() + "\n计数：" + dateBucket.getDocCount());
            Aggregation group_by_tag = dateBucket.getAggregations().asMap().get("by_tag");
            StringTerms terms = (StringTerms) group_by_tag;
            Iterator<StringTerms.Bucket> tagsBucket = terms.getBuckets().iterator();
            while (tagsBucket.hasNext()) {
                StringTerms.Bucket tagBucket = tagsBucket.next();
                System.out.println("\t标签名称：" + tagBucket.getKey() + "\n\t数量：" + tagBucket.getDocCount());
                Aggregation avg_price = tagBucket.getAggregations().get("avg_price");
                Avg avg = (Avg) avg_price;
                System.out.println("\t平均价格：" + avg.getValue() + "\n");
            }
        }

    }


}
